﻿#region Header

/*
Remote views based on linq
By

Pascal Hauser 
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

and

Raphael Gfeller
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

*/

#endregion

#region Usings

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;
using Sebarf.Core.Interfaces;
using Sebarf.Diagnostics.Interfaces;
using Sebarf.Services.Interfaces;

#endregion

namespace InterLinq.Test.UI {
	/// <summary>
	/// displays statistics data from services
	/// </summary>
	public partial class ServicesStatisticsView : UserControl {
		#region Public Methods

		/// <summary>
		/// ctr
		/// </summary>
		private ServicesStatisticsView() {
			InitializeComponent();

			// create brushes for the chart
			var l = new List<Brush>(brushes);
			const int percolor = 4;
			for (int i = 2; i < percolor; i++) {
				for (int j = 2; j < percolor; j++) {
					for (int k = 2; k < percolor; k++) {
						l.Add(
							new SolidColorBrush(Color.FromRgb((byte)(256 * i / percolor), (byte)(256 * j / percolor),
																(byte)(256 * k / percolor))));
					}
				}
			}
			brushes = l.ToArray();
		}

		public ServicesStatisticsView(IServiceLocatorService data)
			: this() {
			Check.ArgumentNotNull(data, "data");
			m_data = data;

			m_items.Children.Clear();

			m_worker.Tick += OnTimerTick;
			m_worker.Interval = new TimeSpan(0, 0, 2);
			m_worker.Start();
		}

		private void OnTimerTick(object sender, EventArgs e) {
			if (ActualHeight < 10) {
				return;
			}
			Content.Children.Clear();
			var service = m_data.GetRegisteredService<IDiagnosticsDataCollectorService>();
			int index = 0;
			if (m_items.Children.Count == 0) {
				foreach (var entry in service.GetCollectedDiagnosticsDataOverTime()) {
					m_items.Children.Add(new CheckBox { IsChecked = false, Tag = entry, Content = entry.Key, Background = brushes[index] });
					index++;
				}
			}

			double minValue = double.MaxValue;
			double maxValue = double.MinValue;
			int count = 500;
			foreach (CheckBox entry in m_items.Children) {
				if (entry.IsChecked.Value) {
					var orignalEntry = (KeyValuePair<String, List<ExtendedServiceStatisticEntry>>)entry.Tag;

					KeyValuePair<string, List<ExtendedServiceStatisticEntry>> serviceStatistics =
						(from p in service.GetCollectedDiagnosticsDataOverTime() where p.Key == orignalEntry.Key select p).First();
					if (serviceStatistics.Value.Count > 0 && serviceStatistics.Value[0].ServiceStatisticEntry.IsNumericEntry) {
						maxValue = Math.Max(maxValue, serviceStatistics.Value.Max(x => (double)x.ServiceStatisticEntry.CollectedValue));
						minValue = Math.Min(minValue, serviceStatistics.Value.Min(x => (double)x.ServiceStatisticEntry.CollectedValue));
						count = serviceStatistics.Value.Count;
					}
				}
			}

			double xFactor = Content.Width / count;
			double yFactor = Content.Height / (Math.Max(10, Math.Abs((minValue - maxValue))));
			m_min.Content = minValue;
			m_max.Content = maxValue;
			index = 0;
			foreach (CheckBox entry in m_items.Children) {
				if (entry.IsChecked.Value) {
					var orignalEntry = (KeyValuePair<String, List<ExtendedServiceStatisticEntry>>)entry.Tag;

					KeyValuePair<string, List<ExtendedServiceStatisticEntry>> serviceStatistics =
						(from p in service.GetCollectedDiagnosticsDataOverTime() where p.Key == orignalEntry.Key select p).First();
					if (serviceStatistics.Value.Count > 0 && serviceStatistics.Value[0].ServiceStatisticEntry.IsNumericEntry) {
						int xindex = 0;
						Point[] points =
							serviceStatistics.Value.Select(
								x => new Point(xFactor * (xindex++), yFactor * (maxValue - (double)x.ServiceStatisticEntry.CollectedValue))).
								ToArray();

						var line = new PolyLineSegment(points, true);
						var pathFigure1 = new PathFigure();
						pathFigure1.StartPoint = points[0];
						pathFigure1.Segments.Add(line);
						var myPathGeometry = new PathGeometry();
						myPathGeometry.Figures.Add(pathFigure1);
						var p = new Path();
						p.Stroke = brushes[index];
						p.StrokeThickness = 1;
						p.Data = myPathGeometry;
						Content.Children.Add(p);
					}
				}
				index++;
			}
		}

		#endregion

		#region Private Fields

		private readonly Brush[] brushes = new Brush[] {
		                                               	Brushes.Red, Brushes.Blue, Brushes.Brown, Brushes.Khaki, Brushes.Green,
		                                               	Brushes.HotPink, Brushes.LavenderBlush, Brushes.LightCyan
		                                               };

		private readonly IServiceLocatorService m_data;
		private readonly DispatcherTimer m_worker = new DispatcherTimer();

		#endregion
	}
}